package com.tedu.api.list;

import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
import org.junit.Test;

import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * 迭代器   打印集合元素【接口】
 * 集合提供自己一套输出集合元素方法---迭代器【类似for  增强for】
 * 包位置:java.util
 * Iterator   接口
 * 该接口是集合接口  提供了遍历元素的相关操作:问 取  删
 * iterator ()方法   返回值Iterator
 * 作用：获取一个用于遍历当前集合迭代器的实现类实例
 * <p>
 * 遍历规则：问 取 删（删不是必须操作）
 */
public class Collection_iterator {
    @Test
    public void testIterator() {
        //创建集合
        Collection c1 = new ArrayList();
        c1.add("one");
        c1.add("two");
        c1.add("three");
        c1.add("four");
        c1.add("five");
        c1.add("six");
        // 作用：获取一个用于遍历当前集合迭代器的实现类实例
        Iterator it = c1.iterator();
        //拿到集合的所有元素      封装到迭代器创建对象过程---理解迭代器实例
        //使用Iterator--获取集合的某个元素，规则  问  取  删
        //Iterator接口---hasNext()获取集合元素
        //思考：如果说：300个元素---循环  while   次数不限定
        while (it.hasNext()) {
            //1 问：  集合是否有元素
            //迭代器集合：获取元素   |   next()获取元素  返回值Object
            String str = (String) it.next();//2 取：获取集合元素
            System.out.println("迭代器" + str);
        }
        //迭代器是否改变我的集合的元素内容
        System.out.println(c1);
    }

    /**
     * 试一试
     * 普通for---遍历c1集合   集合：size
     * 语法:for(int i=o;i<c1.size;i++){}
     * 增强for---遍历c1集合    集合：Object
     * c.remove("#")是Collection的删除方法  并不是迭代方法
     * 语法：for(Object c:c1){}
     * Iterator迭代器---集合提供接口   √
     */
    @Test
    public void testCollection() {
        //创建集合
        Collection c1 = new ArrayList();
        c1.add("one");
        c1.add("two");
        c1.add("three");
        c1.add("four");
        c1.add("five");
        c1.add("six");
        //普通for   遍历集合
        //     for (int i = 0; i < c1.size(); i++) {
        //      System.out.println("普通for:" + c1[]);//打印:
        //     }
        //增强for   遍历集合
        for (Object c : c1) {
            System.out.println("增强for:" + c);
        }
    }

    /**
     * remove（）删除  Iterator迭代值   增强for
     * 作用：删除相同的元素数据，提醒：:问，取next方法【删】
     */
    @Test
    public void testRemove() {
        Collection c = new ArrayList();
        c.add("西游记");
        c.add("#");
        c.add("水浒传");
        //需求通过迭代器删除#好
        Iterator it = c.iterator();
        while (it.hasNext()) {//问：有没有元素
            String str = (String) it.next();    //取：有元素--打印元素
            //  c.remove("#");//Collection中存在remove()
            //删除一定是迭代器
            if ("#".equals(str)) {//如果#是我们拿到的str元素中#
                it.remove();   //那么，删除元素
            }
        }
        System.out.println("迭代器删除:" + c);
    }

    /**
     * 增强for--底层使用Iterator迭代器
     * 需求：删除集合中的#
     */
    @Test
    public void testFor() {
        Collection c = new ArrayList();
        c.add("西游记");
        c.add("#");
        c.add("水浒传");
        for (Object o : c) {//增强for  类型引用   集合引用
            String str = (String) o;//强转  拿到字符串类型
            //   if ("#".equals(str)) {
            c.remove(o);
            //   }
        }
        System.out.println("删除集合的元素:" + c);

    }

    /**
     * E   element  泛型   JDK1.5新特性
     * 结合集合出现  约束我们集合的类型[基本数据类型  引用数据类型   包装类】
     * 泛型的原型：Object  泛型是翻译器认可的，JVM虚拟机并不认可
     * 使用泛型是告诉编译器应该把泛型当初Object类型执行  便于编译器检查
     * 类型以及自动造型操作：
     * JDK1.7 泛型使用
     * Collection<类型：基本类型 引用类型 包装类>c=new Arraylist<类型：基本类型 引用类型 包装类>
     * <p>
     * 泛型:自动推导：通配符： ？ 通配符:表示任意类型
     * Collection<类型：基本类型 引用类型 包装类>c=new Arraylist<类型：基本类型 引用类型 包装类>
     * <p>
     * Collection<类型 ? extends/super 父类/接口/类>c=new Arraylist<>
     * 优点：保证类型安全  提高代码重用型和灵活性
     * ---限制集合传入的对应类型
     */
    @Test
    public void testType() {
        //针对泛型自动推导   通配符 ？
        Collection<?> c1 = new ArrayList<>();
        c1.add(null);   //结论：并不是匹配所有类型，
        Collection<String> c = new ArrayList<String>();
        c.add("123");
        c.add("456");
        c.add("789");
        //遍历Iterator
        Iterator<String> it = c.iterator();
        while (it.hasNext()) {
            String str = it.next();
            System.out.println(str);
        }
    }
}

class Fruit {//父类
    private String name; //成员变量

    public Fruit(String name) {//有参构造器
        this.name = name;
    }

    public String getName() {//方法
        return name;
    }
}

class Apple extends Fruit {//子类

    public Apple() {
        super("苹果"); //通用父类有参数构造器  传入name名称
    }
}

class Orange extends Fruit {//子类2

    public Orange() {
        super("橘子");//调用父类有参数构造器  传入name名称
    }
}

//测试类---泛型上界
class TestJob {
    // 泛型上界 1.定义静态方法  指定泛型规则--集合中类型约定为Apple与Orange
    public static void printFruit(Collection<? extends Fruit> fruits) {
        //2.增强for循环打印  集合中类型约定为Apple与Orange
        for (Fruit fruit : fruits) {
            //3.方法能进入   Apple或Orange---打印名字
            System.out.println(fruit.getName());
        }
    }

    //主方法测试功能
    public static void main(String[] args) {
        Collection<Apple> apples = new ArrayList<>();
        apples.add(new Apple()); //集合对象添加：Apple对象
        Collection<Orange> oranges = new ArrayList<>();
        oranges.add(new Orange()); //集合对象添加：Orange对象
        printFruit(apples);
        printFruit(oranges);
    }
}

























